package com.geline.easyexcel.handler;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Excel单元格填充公式
 *
 * @author: mengxin
 * @date: 2024/1/29 10:52
 */
@Slf4j
public class CellFormulaWriteHandler implements CellWriteHandler {

    //单元格公式<列坐标, 公式字符串>
    private Map<Integer, String> columnFormulaMap;

    public CellFormulaWriteHandler(Class clazz) {
        this.columnFormulaMap = parseFormulaMap(clazz);
    }

    public CellFormulaWriteHandler(Map<Integer, String> columnFormulaMap) {
        this.columnFormulaMap = columnFormulaMap;
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                 List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        int columnIndex = cell.getColumnIndex();
        String formula = columnFormulaMap.get(columnIndex);
        if(StrUtil.isNotBlank(formula)){
            //替换公式 100*N{rowIndex}/P{rowIndex}
            formula = formula.replace("{rowIndex}", String.valueOf(cell.getRowIndex() + 1));
            //写入公式
            cell.setCellFormula(formula);
        }
    }

    public Map<Integer, String> parseFormulaMap(Class head) {
        Map<Integer, String> formulaMap = new HashMap<>();

        Field[] fields = head.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            ExcelProperty property = field.getAnnotation(ExcelProperty.class);
            if (property != null) {
                int index = property.index();
                String format = property.format();
                if(StrUtil.isNotBlank(format)){
                    if(index==-1){
                        throw new RuntimeException(String.format("%s can not find @ExcelProperty(index=X) !", field.getName()));
                    }else {
                        formulaMap.put(index, format);
                    }
                }
            }
        }
        return formulaMap;
    }
}
